using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;

namespace Babylon.Toolbox
{
    partial class StatesManager
    {
        long currentBlendKey = -1;
        BlendFunction colorBlendFunction = BlendFunction.Add;
        BlendFunction alphaBlendFunction = BlendFunction.Add;
        Blend alphaSourceBlend = Blend.SourceAlpha;
        Blend alphaDestinationBlend = Blend.InverseSourceAlpha;
        Blend colorSourceBlend = Blend.SourceAlpha;
        Blend colorDestinationBlend = Blend.InverseSourceAlpha;
        readonly Dictionary<long, BlendState> blendStates = new Dictionary<long, BlendState>();

        long ComputeBlendKey()
        {
            return (((int)colorDestinationBlend) << 22) + (((int)colorSourceBlend) << 18) + (((int)alphaDestinationBlend) << 14) +
                (((int)alphaSourceBlend) << 10) + (((int)currentCullMode) << 6) + (((int)alphaBlendFunction) << 3) + ((int)colorBlendFunction);
        }


        public BlendFunction ColorBlendFunction
        {
            get { return colorBlendFunction; }
            set
            {
                colorBlendFunction = value;
            }
        }

        public BlendFunction AlphaBlendFunction
        {
            get { return alphaBlendFunction; }
            set
            {
                alphaBlendFunction = value;
            }
        }

        public Blend AlphaSourceBlend
        {
            get { return alphaSourceBlend; }
            set
            {
                alphaSourceBlend = value;
            }
        }

        public Blend AlphaDestinationBlend
        {
            get { return alphaDestinationBlend; }
            set
            {
                alphaDestinationBlend = value;
            }
        }

        public Blend ColorSourceBlend
        {
            get { return colorSourceBlend; }
            set
            {
                colorSourceBlend = value;
            }
        }

        public Blend ColorDestinationBlend
        {
            get { return colorDestinationBlend; }
            set
            {
                colorDestinationBlend = value;
            }
        }

        public void ApplyBlendState()
        {
            long key = ComputeBlendKey();

            if (key == currentBlendKey)
                return;

            BlendState blendState;

            if (!blendStates.TryGetValue(key, out blendState))
            {
                blendState = new BlendState
                                      {
                                          ColorBlendFunction = colorBlendFunction,
                                          AlphaBlendFunction = alphaBlendFunction,
                                          AlphaSourceBlend = alphaSourceBlend,
                                          AlphaDestinationBlend = alphaDestinationBlend,
                                          ColorSourceBlend = colorSourceBlend,
                                          ColorDestinationBlend = colorDestinationBlend
                                      };

                blendStates.Add(key, blendState);
            }

            currentBlendKey = key;
            Device.BlendState = blendState;
        }
    }
}
